package notice

import (
	"context"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/util/gconv"
	"time"
	"xr-game-server/core/constants/cmd"
	"xr-game-server/core/event"
	"xr-game-server/core/httpserver"
	"xr-game-server/core/push"
	"xr-game-server/core/snowflake"
	"xr-game-server/core/xrtimer"
	"xr-game-server/dao/noticedao"
	"xr-game-server/dto/noticedto"
	"xr-game-server/entity"
	"xr-game-server/gameevent"
)

var noticeArray []*entity.Notice

func Init() {

	noticeArray = noticedao.GetAllStatus()
	for _, val := range noticeArray {
		if val.CanSend() {
			SendNotice(val)
		} else {
			now := time.Now()
			//到时间发送通告
			xrtimer.AddOnce(gctx.New(), val.StartTime.Sub(now), func(ctx context.Context) {
				SendNotice(val)
			})
		}
	}
	//订阅公告
	event.Sub(gameevent.NoticeEvent, onNoticeEvent)
	event.Sub(event.Online, online)
}

func onNoticeEvent(data any) {
	if data == nil {
		return
	}
	notice := data.(*gameevent.NoticeEventData)
	pushData := noticedto.NewPushAppNotice(notice)
	push.Broadcast(cmd.Notice, pushData)
}

func SendNotice(notice *entity.Notice) {
	pushData := noticedto.NewPushDtoByEntity(notice)
	push.Broadcast(cmd.Notice, pushData)
}

func online(data any) {
	eventData := data.(*event.OnlineData)
	for _, val := range noticeArray {
		if val.CanSend() {
			pushData := noticedto.NewPushDtoByEntity(val)
			push.Data(eventData.RoleId, cmd.Notice, pushData)
		}
	}
}

func AddNotice(ctx context.Context, add *noticedto.AddNoticeReq) (bool, error) {
	notice := entity.NewNotice()
	gconv.Struct(add, notice)
	notice.ID = snowflake.GetId()
	noticedao.Save(notice)
	if notice.CanSend() {
		SendNotice(notice)
	} else {
		now := time.Now()
		//到时间发送通告
		xrtimer.AddOnce(gctx.New(), notice.StartTime.Sub(now), func(ctx context.Context) {
			SendNotice(notice)
		})
	}
	//刷新跑马灯缓存
	noticeArray = noticedao.GetAllStatus()
	return true, nil
}

func AddOnceNotice(ctx context.Context, req *noticedto.AddOnceNoticeReq) (res bool, err error) {
	pushData := noticedto.NewOncePushDto(req)
	push.Broadcast(cmd.Notice, pushData)
	return true, err
}

func Page(ctx context.Context, req *noticedto.GetNoticeReq) (res *httpserver.CMSQueryResp, er error) {
	return httpserver.NewCMSQueryResp(noticedao.Page(req)), nil
}
